﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CacheService.Standard;
using Common.Standard;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using WebApi.Common.Standard;
using Wx.Standard;
using Wx.Standard.IService;
using Wx.Standard.Model.App;
using Wx.Standard.Options;
using Wx.Standard.Service;

namespace WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class WxAppController : Controller
    {
        private ICache cache;
        private IApp wxApp;
        //private SqlSugar.SqlSugarClient db = DbProvider.GetMasterInstance();
        public WxAppController(ICache _cache, WxApp _wxApp)
        {
            this.cache = _cache;
            this.wxApp = _wxApp.App;
        }
        [HttpGet, Filter.NoLogin]
        public async Task<ApiResult<object>> Index()
        {
            await Task.CompletedTask;
            return new ApiResult<object>() { data = DateTime.Now };
        }
        #region 登录
        [HttpGet, Filter.NoLogin]
        public async Task<ApiResult<object>> Login(string code, string fromurl = "")
        {
            if (!string.IsNullOrWhiteSpace(code))
            {
                var wxKey = wxApp.GetKey(code);

                var token = wxKey.session_key.ToMD5();
                var db = DbProvider.GetMasterInstance();
                var user = db.Queryable<Models.not_user>().Where(it => it.openid == wxKey.openid).First();
                if (user == null)
                {
                    user = new Models.not_user()
                    {
                        openid = wxKey.openid,
                        session_key = wxKey.session_key,
                        addtime = DateTime.Now,
                        usertoken = token,
                        fromurl = fromurl
                    };
                    await db.Insertable<Models.not_user>(user).ExecuteCommandAsync();
                }
                else
                {
                    var oldToken = user.usertoken;
                    if (cache.hasKey($"{oldToken}:user"))
                    {
                        cache.delete($"{oldToken}:user");
                        cache.delete($"{oldToken}:openid");
                    }
                    await db.Updateable<Models.not_user>().UpdateColumns(it => it.usertoken == token)
                         .Where(it => it.openid == wxKey.openid).ExecuteCommandAsync();
                    user.usertoken = token;
                }
                cache.set($"{token}:user", user);
                cache.set($"{token}:openid", wxKey);
                return new ApiResult<object>() { data = new { usertoken = token }, message = "操作成功" };
            }
            else
            {
                return new ApiResult<object>() { success = false, message = "参数错误" };
            }
        }
        #endregion
        #region 认证 => 验证用户基本信息
        [HttpPost]
        public async Task<ApiResult<object>> UpDataUserInfo(SmallApp_InfoData dy)
        {
            var token = Request.HttpContext.Items["token"];
            var cacheSessionKey = cache.get<SmallApp_KeyInfo>($"{token}:openid");
            if (cacheSessionKey == null) return new ApiResult<object>() { statusCode = 200, success = false, message = "无效登录" };
            if (dy == null) return new ApiResult<object>() { statusCode = 200, success = false, message = "参数错误" };
            var si = dy as SmallApp_InfoData;
            var user = wxApp.GetUser((SmallApp_InfoData)si, cacheSessionKey.session_key);
            if (user == null) return new ApiResult<object>() { statusCode = 200, success = false, message = "解密用户数据失败" };
            var db = DbProvider.GetMasterInstance();
            await db.Updateable<Models.not_user>(new { avatar = user.avatarUrl, nickname = user.nickName, country = user.country, city = user.city, gender = user.gender })
                /*.UpdateColumnsIF(it => it.avatar == user.avatarUrl)
                .UpdateColumns(it => it.nickname == user.nickName)
                .UpdateColumns(it => it.country == user.country)
                .UpdateColumns(it => it.city == user.city)
                .UpdateColumns(it => it.gender == user.gender)*/
                .Where(it => it.usertoken == (token.ToString()) /*&& (SqlSugar.SqlFunc.IsNullOrEmpty(it.nickname) || SqlFunc.IsNullOrEmpty(it.avatar))*/)
                .ExecuteCommandAsync();
            return new ApiResult<object>() { data = new { }, message = "操作成功" };
        }
        #endregion

        #region 期号 => 期项奖品
        [HttpGet, Filter.NoLogin]
        public async Task<ApiResult<List<Models.WxApp.LuckItem>>> GetLuck()
        {
            var db = DbProvider.GetMasterInstance();
            var list = new List<Models.WxApp.LuckItem> { };
            list = await db.Queryable<Models.not_luck>().Where(it => it.zt == 0 && it.endtime >= DateTime.Now)
                .OrderBy(it => it.id, OrderByType.Desc).Select<Models.WxApp.LuckItem>(it => new Models.WxApp.LuckItem
                {
                    id = it.id,
                    patronname = it.sitename,
                    goodsimg = it.goodsimg,
                    goodsname = it.goodsname,
                    count = SqlFunc.ToInt32(it.lucknum),
                    endtime = SqlFunc.ToDate(it.endtime),
                    lottery_time = it.lottery_time,
                    zt = it.zt
                }).ToListAsync();
            return new ApiResult<List<Models.WxApp.LuckItem>>() { data = list, message = "操作成功" };
        }
        [HttpGet, Filter.NoLogin]
        public async Task<ApiResult<object>> GetLuckDetail(int luckid)
        {
            var db = DbProvider.GetMasterInstance();
            var luckitem = await db.Queryable<Models.not_luck>().Where(it => it.id == luckid).FirstAsync();

            return new ApiResult<object>() { data = luckitem, message = "操作成功" };
        }

        [HttpGet, Filter.NoLogin]
        public async Task<ApiResult<object>> GetLuckGessList(int luckid, int page)
        {
            var db = DbProvider.GetMasterInstance();
            //所有参与的用户ID
            /*
            var list = await db.Queryable<Models.not_luckitem>().GroupBy(it => it.openid)
                .Where(it => it.luckid == luckid).Select(it=>it.openid).ToListAsync();*/

            var list = await db.Queryable<Models.not_luckitem, Models.not_user>((sc, st) => sc.openid == st.id)
                .Where(sc => sc.luckid == luckid).OrderBy(sc => sc.addtime, OrderByType.Desc).Select<Models.WxApp.User>((sc, st) => new Models.WxApp.User() { OpenId = st.openid, NickName = st.nickname, Avatar = st.avatar }).ToPageListAsync(page, 30);

            return new ApiResult<object>() { data = list, message = "操作成功" };
        }

        #endregion
        #region 竞猜
        [HttpGet]
        public async Task<ApiResult<object>> GuessAdd(int luckid, decimal guess)
        {
            var db = DbProvider.GetMasterInstance();
            var token = Request.HttpContext.Items["token"];
            var user = cache.get<Models.not_user>($"{token}:user");
            if (user == null)
            {
                return new ApiResult<object>() { data = "用户未授权", message = "操作失败", success = false, statusCode = 500 };
            }

            var activitie = await db.Queryable<Models.not_luck>().Where(it => it.id == luckid && it.zt == 0).FirstAsync();
            if (activitie == null)
                return new ApiResult<object>() { data = "活动已经线束", message = "操作失败", success = false, statusCode = 500 };
            var luck = await db.Queryable<Models.not_luckitem>()
                .Where(it => it.luckid == luckid && it.openid == user.id).FirstAsync();
            //第一次参与
            if (luck == null)
            {
                luck = new Models.not_luckitem()
                { luckid = luckid, openid = user.id, luckvalue = guess, luckcount = 1, addtime = DateTime.Now };
                await db.Insertable(luck).ExecuteCommandAsync();
            }
            else
            {
                var max = await db.Queryable<Models.not_luckitem>()
                    .Where(it => it.luckid == luckid && it.openid == user.id).MaxAsync<int>(it => SqlFunc.ToInt32(it.luckcount)
                    );
                //最多可参与20次
                if (max > 20)
                {
                    return new ApiResult<object>() { data = "超过最大可参与次数", message = "操作失败", success = false, statusCode = 500 };
                }
                await db.Insertable(new Models.not_luckitem()
                { luckid = luckid, openid = user.id, luckvalue = guess, luckcount = max + 1, addtime = DateTime.Now }).ExecuteCommandAsync();
            }

            return new ApiResult<object>() { data = { }, message = "操作成功" };
        }
        /// <summary>
        /// 参与过的
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<object>> GuessList()
        {
            var db = DbProvider.GetMasterInstance();
            var token = Request.HttpContext.Items["token"];
            var user = cache.get<Models.not_user>($"{token}:user");
            if (user == null)
            {
                return new ApiResult<object>() { data = "用户未授权", message = "操作失败", success = false, statusCode = 500 };
            }

            var list = await db.Queryable<Models.not_luck, Models.not_luckitem>((sc, it) => sc.id == it.luckid)
                .Where((sc, it) => it.openid == user.id).OrderBy(it => it.id, OrderByType.Desc).Select<Models.WxApp.LuckItem>((sc, it) =>
                       new Models.WxApp.LuckItem
                       {
                           id = it.id,
                           patronname = sc.sitename,
                           goodsimg = sc.goodsimg,
                           goodsname = sc.goodsname,
                           count = SqlFunc.ToInt32(sc.lucknum),
                           endtime = SqlFunc.ToDate(sc.endtime),
                           lottery_time = sc.lottery_time,
                           zt = sc.zt
                       }).ToListAsync();
            return new ApiResult<object>() { data = list, message = "操作成功" };
        }

        /// <summary>
        /// 我的竞猜详情
        /// </summary>
        /// <param name="luckid">todo: describe luckid parameter on GuessDetail</param>
        [HttpGet]
        public async Task<ApiResult<object>> GuessDetail(int luckid)
        {
            var db = DbProvider.GetMasterInstance();
            var token = Request.HttpContext.Items["token"];
            var user = cache.get<Models.not_user>($"{token}:user");
            if (user == null)
            {
                return new ApiResult<object>() { data = "用户未授权", message = "操作失败", success = false, statusCode = 500 };
            }
            var luckitem = await db.Queryable<Models.not_luck>().Where(it => it.id == luckid).FirstAsync();
            var luckgesslist = await db.Queryable<Models.not_luckitem>()
                .Where(it => it.luckid == luckid && it.openid == user.id).OrderBy(it => it.addtime, OrderByType.Desc).ToListAsync();
            return new ApiResult<object>() { data = new { luckitem = luckitem, gesslist = luckgesslist }, message = "操作成功" };
        }

        #endregion
    }
}